home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / t3_1 / encorsrc.lha / encore_sources / sys / big_fixnum.t < prev    next >
Text File  |  1988-05-02  |  3KB  |  84 lines

  1. (herald big_fixnum
  2.   (env tsys))
  3.  
  4. ;;; This file contains fixnum routines which require other number
  5. ;;; types to be present.
  6.  
  7. (define (fixnum-negative-expt x y)
  8.   (ratio 1 (fixnum-expt x (fx- 0 y))))
  9.  
  10. ;;; Careful fixnum routines:
  11.  
  12. ;;; Assume N bit arithmetic, machine result is N bits (what the hardware
  13. ;;; gives).  The "true result" may be up to N+1 bits sign of result on
  14. ;;; overflow.
  15. ;;;
  16. ;;;   if (A-B) overflows, A and B have different signs,
  17. ;;;            true result is sign of A
  18. ;;;   if (A+B) overflows, A and B have the same sign,
  19. ;;;            true result is the same sign
  20. ;;;
  21. ;;;   When the sign of the true result is positive, the magnitude of the
  22. ;;;     true result is the machine result.
  23. ;;;
  24. ;;;   When the sign of the true result is negative, the magnitude of the
  25. ;;;     true result is the magnitude of the N+1 bit number
  26. ;;;     formed by the carry bit and the machine result.
  27. ;;;
  28. ;;; Subtle issue:
  29. ;;; Taking the arithmetic complement of an N+1 bit number requires N+1 bits
  30. ;;; in all cases except for the most negative number which requires N+2 bits
  31. ;;; to complement.  Fortunately we only want the magnitude, which is
  32. ;;; the arithmetic complement of the hardware result, except when the
  33. ;;; N+1 bit number is the most negative N+1 bit number (carry bit = 1,
  34. ;;; fixnum = 0), in which case the magnitude is that same N+1 bit number.
  35. ;;;
  36. ;;; Aren't you glad I figured this out?
  37. ;;;
  38. ;;;  I'd be happier if you had also figured out the most negative number can
  39. ;;; only occur on an add overflow and not on a subtraction.  Also, a
  40. ;;; subtraction cannot overflow and give a result of 0.  Thus the CARRY?
  41. ;;; argument to FIXNUM-AFTERMATH->BIGNUM was unnecessary.
  42.  
  43. ;;; This routine takes wreckage from an overflowed ADD or SUB and
  44. ;;; makes a bignum out of it.  SIGN is computed as described above.
  45.  
  46. (define (fixnum-aftermath->bignum sign fixnum)
  47.   (cond ((fx= sign -1)
  48.          (cond ((fx= fixnum 0)     ; min N+1 bit fixnum
  49.                 (sign&magnitude->bignum -1 t 0))
  50.                (else
  51.                 (sign&magnitude->bignum -1 nil (fixnum-negate fixnum)))))
  52.         (else
  53.          (sign&magnitude->bignum 1 nil fixnum))))
  54.  
  55. (define (fixnum-add-carefully x y)
  56.   (receive (sum overflow?)
  57.            (fixnum-add-with-overflow-xxx x y)
  58.     (cond (overflow?
  59.            (fixnum-aftermath->bignum (if (fx< x 0) -1 1)  ; sign of either
  60.                                      sum))
  61.           (else sum))))
  62.  
  63. (define (fixnum-subtract-carefully x y)
  64.   (receive (diff overflow?)
  65.            (fixnum-subtract-with-overflow-xxx x y)
  66.     (cond (overflow?
  67.            (fixnum-aftermath->bignum (if (fx< x 0) -1 1)  ; sign of first
  68.                                      diff))
  69.           (else diff))))
  70.  
  71. (define (fixnum-multiply-carefully x y)
  72.   (let ((res (fx+ (fixnum-howlong (fixnum-abs x))
  73.                   (fixnum-howlong (fixnum-abs y)))))
  74.     (cond ((fx>= res *bits-per-fixnum*)
  75.            (bignum-multiply (fixnum->bignum x) (fixnum->bignum y)))
  76.           (else (fx* x y)))))
  77.  
  78. (define fixnum-divide-carefully ratio)
  79.  
  80. ;(define (fixnum-negate-carefully fixnum)
  81. ;  (cond ((fx= fixnum most-positive-fixnum)  ;;; Huh? most-negative-fixnum is the problem.
  82. ;         (fixnum->bignum fixnum))
  83. ;        (else (fixnum-negate fixnum))))
  84.